package com.zsr.xmall.auth.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.zsr.common.constant.auth.AuthConstant;
import com.zsr.common.constant.auth.AuthSourceTypeConstant;
import com.zsr.common.utils.HttpUtils;
import com.zsr.common.utils.R;
import com.zsr.common.vo.auth.GiteeSocialUserVO;
import com.zsr.common.vo.auth.MemberResponseVO;
import com.zsr.xmall.auth.feign.MemberFeignService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

/**
 * 处理社交登录请求
 */
@Slf4j
@Controller
public class OAuth2Controller {

    @Autowired
    private MemberFeignService memberFeignService;

    @GetMapping("/oauth2.0/gitee/success")
    public String gitee(@RequestParam("code") String code, HttpSession session, HttpServletResponse servletResponse) throws Exception {
        //文档地址：https://gitee.com/api/v5/oauth_doc#/
        //https://gitee.com/oauth/authorize?client_id=2310ffccce545d2ca67711f60fd56ba6108dc1af0ab5f9f5936f6c0ad75abb29&redirect_uri=http://xmall.com/oauth2.0/gitee/success&response_type=code
        Map<String, String> map = new HashMap<>(5);
        map.put("grant_type", "authorization_code");
        map.put("code", code);
        map.put("client_id", "2310ffccce545d2ca67711f60fd56ba6108dc1af0ab5f9f5936f6c0ad75abb29");
        map.put("redirect_uri", "http://xmall.com/oauth2.0/gitee/success");
        map.put("client_secret", "e985df53160d4b3e5f96ae7a5fd818eb12f8bf33e213436f9d08157c29df914a");

        HttpResponse response = HttpUtils.doPost("gitee.com", "oauth/token", "post", null, null, map);
        //1.根据code获取access_token
        if (response.getStatusLine().getStatusCode() == 200) {
            //获取到accessToken
            String s = EntityUtils.toString(response.getEntity());
            /*{
                "access_token": "4b79c9e10cdfec63afb069a45540b1dc",
                "token_type": "bearer",
                "expires_in": 86400,
                "refresh_token": "adce9be145f6662d6e068460da98a953b9e852335dc04db8117c77ee5eba5189",
                "scope": "user_info",
                "created_at": 1663126517
            }*/
            GiteeSocialUserVO giteeSocialUserVO = JSON.parseObject(s, GiteeSocialUserVO.class);
            //1) 为当前社交用户生成会员信息账号
            Map<String, String> paramMap = new HashMap<>(1);
            paramMap.put("access_token", giteeSocialUserVO.getAccess_token());
            HttpResponse accessResponse = HttpUtils.doGet("gitee.com", "api/v5/user", "get", null, paramMap);
            String accessJson = EntityUtils.toString(accessResponse.getEntity());

            JSONObject jsonObject = JSON.parseObject(accessJson);
            //填充字段
            giteeSocialUserVO.setUid(jsonObject.getString("id"));
            giteeSocialUserVO.setSourceType(AuthSourceTypeConstant.GITEE);
            giteeSocialUserVO.setName(jsonObject.getString("name"));
            giteeSocialUserVO.setAvatar_url(jsonObject.getString("avatar_url"));

            //远程调用
            R r = memberFeignService.oauthLogin(giteeSocialUserVO);
            if (r.getCode() == 0) {
                // 登录成功
                MemberResponseVO loginUser = r.getData(new TypeReference<MemberResponseVO>() {
                });
                log.info("登录成功：用户：{}", loginUser.toString());

                // 3.信息存储到session中，并且放大作用域（指定domain=父级域名）
                session.setAttribute(AuthConstant.LOGIN_USER, loginUser);
               /* session原理：session是服务器存于内存的一个数据对象(该对象有一个唯一的id,一般称之为sessionId)，
                服务器会将sessionId以cookie的方式发送给浏览器。
                当浏览器再次访问服务器时，会将sessionId发送过来，服务器依据sessionId就可以找到对应的session对象。*/

                /*spring Session实现原理： Springboot 创建一个 springSessionRepositoryFilter的过滤器，将
                 * 原生HttpSession替换成SpringSession, 代码只需配置pom、yaml和配合@EnableRedisHttpSession+
                 * https://docs.spring.io/spring-session/reference/guides/boot-redis.html
                 * */
                //todo 1默认发的令牌，key为session，value为一段字符串。作用域为当前域，需要解决子域session共享问题
                //todo 2使用json的序列化方式来序列化对象数据到redis中，无需实现Serializable接口

                /*原生实现方式： 首次使用session时，spring会自动颁发cookie设置domain，所以这里手动设置cookie很麻烦，采用springsession的方式颁发父级域名的domain权限
                Cookie cookie = new Cookie("JSESSIONID", loginUser.getId().toString());
                cookie.setDomain("gulimall.com");
                servletResponse.addCookie(cookie);*/
                // 跳回首页
                return "redirect:http://gulimall.com";
            } else {
                // 登录失败，调回登录页
                return "redirect:http://auth.gulimall.com/login.html";
            }

        } else {
            return "redirect:http://xmaill.com/login.html";
        }
    }

    @GetMapping("/oauth2.0/weibo/success")
    public String weibo(@RequestParam("code") String code) {

        return "";
    }
}
